﻿using System;
using System.Collections.Generic;
using System.Xml;

namespace yunio._dat_xml
{
    internal class xmlhelper
    {
        /// <summary>
        /// 创建新的 XML 文档（带根节点）
        /// </summary>
        /// <param name="rootName">根节点名称</param>
        /// <returns>XmlDocument 对象</returns>
        public static XmlDocument CreateXmlDocument(string rootName)
        {
            var doc = new XmlDocument();
            doc.AppendChild(doc.CreateXmlDeclaration("1.0", "UTF-8", null)); // 声明头
            doc.AppendChild(doc.CreateElement(rootName)); // 根节点
            return doc;
        }

        /// <summary>
        /// 向指定父节点添加子节点（带文本内容）
        /// </summary>
        /// <param name="parentNode">父节点</param>
        /// <param name="childName">子节点名称</param>
        /// <param name="text">子节点文本内容（可选）</param>
        public static void AddChildNode(XmlNode parentNode, string childName, string text = null)
        {
            var child = parentNode.OwnerDocument.CreateElement(childName);
            if (!string.IsNullOrEmpty(text)) child.InnerText = text;
            parentNode.AppendChild(child);
        }

        /// <summary>
        /// 向指定节点添加属性
        /// </summary>
        /// <param name="node">目标节点</param>
        /// <param name="attrName">属性名</param>
        /// <param name="attrValue">属性值</param>
        public static void AddAttribute(XmlNode node, string attrName, string attrValue)
        {
            var attr = node.OwnerDocument.CreateAttribute(attrName);
            attr.Value = attrValue;
            node.Attributes.Append(attr);
        }
        /// <summary>
        /// 加载 XML 文件到 XmlDocument
        /// </summary>
        public static XmlDocument LoadXmlFile(string filePath)
        {
            var doc = new XmlDocument();
            doc.Load(filePath); // 自动处理编码（根据文件头声明）
            return doc;
        }

        /// <summary>
        /// 根据 XPath 查询首个匹配节点的值
        /// </summary>
        /// <param name="doc">XmlDocument 对象</param>
        /// <param name="xPath">XPath 表达式（如 "/Root/User/Name"）</param>
        /// <returns>节点值（未找到返回 null）</returns>
        public static string SelectSingleNodeValue(XmlDocument doc, string xPath)
        {
            var node = doc.SelectSingleNode(xPath);
            return node?.InnerText;
        }

        /// <summary>
        /// 根据节点路径查询首个匹配节点（简化版，非 XPath）
        /// </summary>
        /// <example>路径格式："Root.User.List.Item"（逐级查找子节点）</example>
        public static XmlNode FindNodeByPath(XmlDocument doc, string nodePath)
        {
            var current = doc.DocumentElement;
            if (current == null) return null;

            foreach (var nodeName in nodePath.Split('.'))
            {
                foreach (XmlElement node in current.ChildNodes)
                    if (node.Name == nodeName) {
                        current = node;
                        goto NEXT;
                    }

                break;
                NEXT:
                continue;
            }
            return current;
        }

        /// <summary>
        /// 修改指定节点的文本内容
        /// </summary>
        public static void UpdateNodeValue(XmlDocument doc, string xPath, string newValue)
        {
            var node = doc.SelectSingleNode(xPath);
            if (node != null) node.InnerText = newValue;
        }

        /// <summary>
        /// 修改指定节点的属性值
        /// </summary>
        public static void UpdateAttributeValue(XmlDocument doc, string xPath, string attrName, string newValue)
        {
            var node = doc.SelectSingleNode(xPath);
            if (node != null && node.Attributes[attrName] != null)
                node.Attributes[attrName].Value = newValue;
        }

        /// <summary>
        /// 删除指定节点
        /// </summary>
        public static void DeleteNode(XmlDocument doc, string xPath)
        {
            var node = doc.SelectSingleNode(xPath);
            if (node != null) node.ParentNode.RemoveChild(node);
        }

        /// <summary>
        /// 保存 XmlDocument 到文件
        /// </summary>
        public static void SaveXmlFile(XmlDocument doc, string filePath)
        {
            doc.Save(filePath);
        }
        public static void load_ns(XmlDocument doc, ref XmlNamespaceManager ns_manager)
        {
            foreach (var ns in loop_namespace(doc.DocumentElement))
                if (string.IsNullOrEmpty(ns.Key))
                    ns_manager.AddNamespace("default", ns.Value);
                else ns_manager.AddNamespace(ns.Key, ns.Value);
        }
        internal static IEnumerable<KeyValuePair<string, string>> loop_namespace(XmlElement element)
        {
            if (element == null) goto END;

            foreach (XmlAttribute attr in element.Attributes)
            {
                if (attr.Prefix == "xmlns")
                    yield return new KeyValuePair<string, string>(attr.LocalName, attr.Value);
                else if (attr.Prefix.StartsWith("xmlns:"))
                    yield return new KeyValuePair<string, string>(attr.LocalName, attr.Value);
            }

            foreach (XmlNode child in element.ChildNodes)
                if (child is XmlElement childElement) foreach (var item in loop_namespace(childElement)) yield return item;
            END:;
        }
    }
}
